home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / chat / talkd.000 / talkd / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-12  |  5.8 KB  |  216 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)process.c    5.10 (Berkeley) 2/26/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * process.c handles the requests, which can be of three types:
  40.  *    ANNOUNCE - announce to a user that a talk is wanted
  41.  *    LEAVE_INVITE - insert the request into the table
  42.  *    LOOK_UP - look up to see if a request is waiting in
  43.  *          in the table for the local user
  44.  *    DELETE - delete invitation
  45.  */
  46. #include <sys/param.h>
  47. #include <sys/stat.h>
  48. #include <sys/socket.h>
  49. #include <netinet/in.h>
  50. #include <protocols/talkd.h>
  51. #include <netdb.h>
  52. #include <syslog.h>
  53. #include <stdio.h>
  54. #include <string.h>
  55. #include <paths.h>
  56.  
  57. CTL_MSG *find_request();
  58. CTL_MSG *find_match();
  59.  
  60. process_request(mp, rp)
  61.     register CTL_MSG *mp;
  62.     register CTL_RESPONSE *rp;
  63. {
  64.     register CTL_MSG *ptr;
  65.     extern int debug;
  66.  
  67.     rp->vers = TALK_VERSION;
  68.     rp->type = mp->type;
  69.     rp->id_num = htonl(0);
  70.     if (mp->vers != TALK_VERSION) {
  71.         syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
  72.         rp->answer = BADVERSION;
  73.         return;
  74.     }
  75.     mp->id_num = ntohl(mp->id_num);
  76.     mp->addr.sa_family = ntohs(mp->addr.sa_family);
  77.     if (mp->addr.sa_family != AF_INET) {
  78.         syslog(LOG_WARNING, "Bad address, family %d",
  79.             mp->addr.sa_family);
  80.         rp->answer = BADADDR;
  81.         return;
  82.     }
  83.     mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family);
  84.     if (mp->ctl_addr.sa_family != AF_INET) {
  85.         syslog(LOG_WARNING, "Bad control address, family %d",
  86.             mp->ctl_addr.sa_family);
  87.         rp->answer = BADCTLADDR;
  88.         return;
  89.     }
  90.     mp->pid = ntohl(mp->pid);
  91.     if (debug)
  92.         print_request("process_request", mp);
  93.     switch (mp->type) {
  94.  
  95.     case ANNOUNCE:
  96.         do_announce(mp, rp);
  97.         break;
  98.  
  99.     case LEAVE_INVITE:
  100.         ptr = find_request(mp);
  101.         if (ptr != (CTL_MSG *)0) {
  102.             rp->id_num = htonl(ptr->id_num);
  103.             rp->answer = SUCCESS;
  104.         } else
  105.             insert_table(mp, rp);
  106.         break;
  107.  
  108.     case LOOK_UP:
  109.         ptr = find_match(mp);
  110.         if (ptr != (CTL_MSG *)0) {
  111.             rp->id_num = htonl(ptr->id_num);
  112.             rp->addr = ptr->addr;
  113.             rp->addr.sa_family = htons(ptr->addr.sa_family);
  114.             rp->answer = SUCCESS;
  115.         } else
  116.             rp->answer = NOT_HERE;
  117.         break;
  118.  
  119.     case DELETE:
  120.         rp->answer = delete_invite(mp->id_num);
  121.         break;
  122.  
  123.     default:
  124.         rp->answer = UNKNOWN_REQUEST;
  125.         break;
  126.     }
  127.     if (debug)
  128.         print_response("process_request", rp);
  129. }
  130.  
  131. do_announce(mp, rp)
  132.     register CTL_MSG *mp;
  133.     CTL_RESPONSE *rp;
  134. {
  135.     struct hostent *hp;
  136.     CTL_MSG *ptr;
  137.     int result;
  138.  
  139.     /* see if the user is logged */
  140.     result = find_user(mp->r_name, mp->r_tty);
  141.     if (result != SUCCESS) {
  142.         rp->answer = result;
  143.         return;
  144.     }
  145. #define    satosin(sa)    ((struct sockaddr_in *)(sa))
  146.     hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr,
  147.         sizeof (struct in_addr), AF_INET);
  148.     if (hp == (struct hostent *)0) {
  149.         rp->answer = MACHINE_UNKNOWN;
  150.         return;
  151.     }
  152.     ptr = find_request(mp);
  153.     if (ptr == (CTL_MSG *) 0) {
  154.         insert_table(mp, rp);
  155.         rp->answer = announce(mp, hp->h_name);
  156.         return;
  157.     }
  158.     if (mp->id_num > ptr->id_num) {
  159.         /*
  160.          * This is an explicit re-announce, so update the id_num
  161.          * field to avoid duplicates and re-announce the talk.
  162.          */
  163.         ptr->id_num = new_id();
  164.         rp->id_num = htonl(ptr->id_num);
  165.         rp->answer = announce(mp, hp->h_name);
  166.     } else {
  167.         /* a duplicated request, so ignore it */
  168.         rp->id_num = htonl(ptr->id_num);
  169.         rp->answer = SUCCESS;
  170.     }
  171. }
  172.  
  173. #include <utmp.h>
  174.  
  175. /*
  176.  * Search utmp for the local user
  177.  */
  178. find_user(name, tty)
  179.     char *name, *tty;
  180. {
  181.     struct utmp ubuf;
  182.     int status;
  183.     FILE *fd;
  184.     struct stat statb;
  185.     char ftty[20];
  186.  
  187.     if ((fd = fopen(_PATH_UTMP, "r")) == NULL) {
  188.         fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP);
  189.         return (FAILED);
  190.     }
  191. #define SCMPN(a, b)    strncmp(a, b, sizeof (a))
  192.     status = NOT_HERE;
  193.     (void) strcpy(ftty, _PATH_DEV);
  194.     while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
  195.         if (SCMPN(ubuf.ut_name, name) == 0) {
  196.             if (*tty == '\0') {
  197.                 status = PERMISSION_DENIED;
  198.                 /* no particular tty was requested */
  199.                 (void) strcpy(ftty+5, ubuf.ut_line);
  200.                 if (stat(ftty,&statb) == 0) {
  201.                     if (!(statb.st_mode & 020))
  202.                         continue;
  203.                     (void) strcpy(tty, ubuf.ut_line);
  204.                     status = SUCCESS;
  205.                     break;
  206.                 }
  207.             }
  208.             if (strcmp(ubuf.ut_line, tty) == 0) {
  209.                 status = SUCCESS;
  210.                 break;
  211.             }
  212.         }
  213.     fclose(fd);
  214.     return (status);
  215. }
  216.